import sys
import time
import json
import re
from PyQt5.QtWidgets import (QApplication, QMainWindow, QTabWidget, QWidget,
                             QVBoxLayout, QHBoxLayout, QLabel, QTextEdit,
                             QPushButton, QComboBox, QLineEdit, QMessageBox,
                             QGroupBox, QProgressBar, QSplitter, QCheckBox,
                             QScrollArea, QGridLayout)
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QSettings, QObject, QTimer
from PyQt5.QtGui import QFont, QIcon, QTextOption
from openai import OpenAI
# 拼音转换库
from pypinyin import lazy_pinyin, Style


# 配置管理类
class AppConfig:
    def __init__(self):
        self.settings = QSettings("AI Poetry Game", "Qianfan Poetry")

    def save_config(self, api_key, base_url, model="ernie-bot-turbo"):
        self.settings.setValue("api_key", api_key)
        self.settings.setValue("base_url", base_url)
        self.settings.setValue("model", model)

    def load_config(self):
        api_key = self.settings.value("api_key", "")
        base_url = self.settings.value("base_url", "https://qianfan.baidubce.com/v2")
        model = self.settings.value("model", "ernie-bot-turbo")
        return api_key, base_url, model

    def clear_config(self):
        self.settings.remove("api_key")
        self.settings.remove("base_url")
        self.settings.remove("model")


# 流式输出信号类
class StreamSignals(QObject):
    new_chunk = pyqtSignal(str)
    finished = pyqtSignal()
    error = pyqtSignal(str)
    debug_info = pyqtSignal(str)
    rate_limit_warning = pyqtSignal(int)
    status_update = pyqtSignal(str)
    progress_update = pyqtSignal(int)  # 进度更新信号


# 拼音转换工具类
class PinyinConverter:
    @staticmethod
    def get_pinyin(text):
        """将中文文本转换为带声调的拼音，忽略非中文字符"""
        if not text or not isinstance(text, str):
            return ""
        # 只保留中文字符进行拼音转换
        chinese_chars = [char for char in text if '\u4e00' <= char <= '\u9fff']
        if not chinese_chars:
            return ""
        # 转换为带声调的拼音，空格分隔
        pinyin_list = lazy_pinyin(''.join(chinese_chars), style=Style.TONE)
        return ' '.join(pinyin_list)

    @staticmethod
    def extract_and_add_pinyin(content):
        """提取内容中【】包裹的诗句，并为其添加拼音标注"""
        if not content:
            return content

        # 正则表达式匹配【】包裹的内容
        pattern = r'【([^】]+)】'

        def replace_with_pinyin(match):
            # 提取【】中的诗句
            poem_line = match.group(1)
            # 获取拼音
            pinyin = PinyinConverter.get_pinyin(poem_line)
            # 如果能生成拼音，则添加；否则返回原内容
            if pinyin:
                return f'【{poem_line}】{pinyin}'
            else:
                return match.group(0)

        # 替换所有匹配的内容
        processed_content = re.sub(pattern, replace_with_pinyin, content)
        return processed_content


# 诗歌API调用类
class PoetryAPI:
    def __init__(self, api_key, base_url, model="ernie-bot-turbo", debug=False, rpm_limit=10):
        self.api_key = api_key
        self.base_url = base_url
        self.model = model
        self.debug = debug
        self.signals = StreamSignals()
        self.request_timestamps = []
        self.rpm_limit = rpm_limit
        self.min_request_interval = 2.0
        self.last_request_time = 0
        self.is_cancelled = False
        self.progress = 0  # 用于跟踪进度

    def cancel_request(self):
        self.is_cancelled = True
        self.signals.debug_info.emit(f"[{time.strftime('%H:%M:%S')}] 请求已取消")

    def handle_rate_limit(self):
        current_time = time.time()

        if self.is_cancelled:
            return False

        # 检查最小请求间隔
        if current_time - self.last_request_time < self.min_request_interval:
            wait_time = self.min_request_interval - (current_time - self.last_request_time)
            self.signals.rate_limit_warning.emit(int(wait_time))
            self.signals.status_update.emit(f"等待{int(wait_time)}秒后继续...")

            # 等待过程中检查是否取消
            start_wait = time.time()
            while time.time() - start_wait < wait_time:
                if self.is_cancelled:
                    return False
                time.sleep(0.1)
            current_time = time.time()

        # 清理1分钟前的请求记录
        self.request_timestamps = [t for t in self.request_timestamps
                                   if current_time - t < 60]

        # 检查RPM限制
        if len(self.request_timestamps) >= self.rpm_limit:
            wait_time = 60 - (current_time - self.request_timestamps[0]) + 1
            self.signals.rate_limit_warning.emit(int(wait_time))
            self.signals.status_update.emit(f"请求过于频繁，等待{int(wait_time)}秒...")

            # 等待过程中检查是否取消
            start_wait = time.time()
            while time.time() - start_wait < wait_time:
                if self.is_cancelled:
                    return False
                time.sleep(0.1)
            current_time = time.time()
            self.request_timestamps = [t for t in self.request_timestamps
                                       if current_time - t < 60]

        # 记录当前请求时间
        self.request_timestamps.append(current_time)
        self.last_request_time = current_time

        if len(self.request_timestamps) > self.rpm_limit * 2:
            self.request_timestamps = self.request_timestamps[-self.rpm_limit:]

        return True

    def couplet_stream(self, upper_sentence, user_requirements=""):
        try:
            self.is_cancelled = False
            self.progress = 0
            self.signals.progress_update.emit(0)

            if not self.handle_rate_limit():
                self.signals.finished.emit()
                return

            client = OpenAI(
                api_key=self.api_key,
                base_url=self.base_url
            )

            base_prompt = f"""你是专为小朋友服务的诗歌助手，现在要和1-6年级的孩子玩对诗游戏。本次对话独立，不参考历史记录。

【核心规则 - 必须严格遵守】：
1. 对于输入的诗句上半句"{upper_sentence}"：
   - 如果是经典诗句（如唐诗宋词），必须用原句的下半句，不能修改
   - 如果不是经典诗句，根据语义和韵律创作适合小朋友的下半句
2. 回应必须符合儿童理解能力，语言*极度简单*、口语化、生动，避免复杂词汇。

【回应结构 - 按顺序输出】：
1. 先给出下半句，用【】包裹（例如：【疑是地上霜】）
2. 用*幼儿园小朋友能听懂的话*解释两句诗的意思，每句解释不超过20个字，要非常直白。
3. 说明诗句是否为经典名句：
   - 若是，注明作者和诗名（简洁，如：李白《静夜思》）
   - 若不是，说明这是为小朋友创作的
4. 最后用一句鼓励的话，激发孩子对古诗的兴趣

【特别说明】：本次回应仅针对"{upper_sentence}"，不涉及其他内容。"""

            if user_requirements.strip():
                base_prompt += f"\n\n【用户额外要求】：{user_requirements}"

            if self.debug:
                self.signals.debug_info.emit(f"[对句请求] 上半句: {upper_sentence}")
                self.signals.debug_info.emit(f"[提示词] {base_prompt}")

            self.signals.status_update.emit("正在生成下半句...")
            completion = client.chat.completions.create(
                model=self.model,
                temperature=0.3,
                messages=[{"role": "user", "content": base_prompt}],
                stream=True
            )

            # 处理流式响应
            for chunk in completion:
                if self.is_cancelled:
                    self.signals.debug_info.emit(f"[{time.strftime('%H:%M:%S')}] 流式响应已取消")
                    self.signals.finished.emit()
                    return

                if self.debug:
                    chunk_dict = chunk.dict()
                    debug_str = json.dumps(chunk_dict, ensure_ascii=False, indent=2)
                    self.signals.debug_info.emit(f"[响应块] {debug_str}")

                chunk_content = ""
                if hasattr(chunk.choices[0].delta, "reasoning_content") and chunk.choices[0].delta.reasoning_content:
                    chunk_content = chunk.choices[0].delta.reasoning_content
                elif chunk.choices[0].delta.content:
                    chunk_content = chunk.choices[0].delta.content

                if chunk_content:
                    # 对内容进行拼音标注处理
                    processed_chunk = PinyinConverter.extract_and_add_pinyin(chunk_content)
                    self.signals.new_chunk.emit(processed_chunk)
                    # 更新进度
                    self.progress = min(self.progress + 2, 95)
                    self.signals.progress_update.emit(self.progress)

                time.sleep(0.05)

            self.signals.progress_update.emit(100)
            self.signals.finished.emit()

        except Exception as e:
            if not self.is_cancelled:
                error_str = f"对句请求失败: {str(e)}"
                if "invalid_model" in str(e):
                    error_str += "\n提示：模型不存在或无权限"
                elif "401" in str(e):
                    error_str += "\n提示：API Key无效，请检查密钥"
                elif "429" in str(e):
                    error_str += "\n提示：请求过于频繁，请稍后再试"
                self.signals.error.emit(error_str)
                self.signals.debug_info.emit(error_str)
            else:
                self.signals.finished.emit()

    def generate_poem_stream(self, keywords, style, user_requirements=""):
        try:
            self.is_cancelled = False
            self.progress = 0
            self.signals.progress_update.emit(0)

            if not keywords:
                error_str = "关键词不能为空"
                self.signals.error.emit(error_str)
                self.signals.debug_info.emit(error_str)
                return

            if not style:
                error_str = "请选择诗歌风格"
                self.signals.error.emit(error_str)
                self.signals.debug_info.emit(error_str)
                return

            if not self.handle_rate_limit():
                self.signals.finished.emit()
                return

            style_guide = {
                "唐诗": "句式整齐，多为五言或七言，押韵对仗工整，意境深远",
                "宋词": "句子长短不一，注重情感表达，风格多样（豪放/婉约）",
                "五言绝句": "四句，每句五个字，结构紧凑，前两句写景后两句抒情",
                "七言绝句": "四句，每句七个字，节奏明快，适合表达瞬间感悟"
            }

            base_prompt = f"""你是儿童诗歌创作家，要为1-6年级小朋友创作{style}。本次创作独立，不参考历史记录。

【创作规则】：
1. 语言必须简单易懂，使用小朋友熟悉的词汇
2. 所有诗句都要标注拼音
3. 若引用经典诗句，必须使用原句并注明出处

【创作流程】：
1. 先推荐2首与关键词"{keywords}"相关的经典古诗，每首包含：
   - 完整诗句（每句用【】包裹）
   - 每句的拼音标注
   - 简单解释（小朋友能懂）
   - 作者和诗名
2. 然后基于关键词创作符合{style}特点的原创诗句：{style_guide[style]}
3. 原创诗句必须包含所有关键词：{keywords}
4. 如果找不到相关的经典古诗，就直接创作原创诗句

【回应结构】：
1. 经典古诗推荐部分（如有）
2. 原创{style}部分，每句诗单独一行并用【】包裹，带拼音
3. 逐句解释原创诗句意思，用*幼儿园小朋友能听懂的话*，每句解释不超过20个字
4. 说明原创诗中描绘的画面和表达的情感，语言要简单

【特别说明】：本次创作仅针对关键词{keywords}，不涉及其他内容。"""

            if user_requirements.strip():
                base_prompt += f"\n\n【用户额外要求】：{user_requirements}"

            if self.debug:
                self.signals.debug_info.emit(f"[生成请求] 关键词: {keywords}, 风格: {style}")
                self.signals.debug_info.emit(f"[提示词] {base_prompt}")

            self.signals.status_update.emit(f"正在查找相关古诗并创作{style}...")
            client = OpenAI(
                api_key=self.api_key,
                base_url=self.base_url
            )
            completion = client.chat.completions.create(
                model=self.model,
                temperature=0.7,
                messages=[{"role": "user", "content": base_prompt}],
                stream=True
            )

            # 处理流式响应
            for chunk in completion:
                if self.is_cancelled:
                    self.signals.debug_info.emit(f"[{time.strftime('%H:%M:%S')}] 流式响应已取消")
                    self.signals.finished.emit()
                    return

                if self.debug:
                    chunk_dict = chunk.dict()
                    debug_str = json.dumps(chunk_dict, ensure_ascii=False, indent=2)
                    self.signals.debug_info.emit(f"[响应块] {debug_str}")

                chunk_content = ""
                if hasattr(chunk.choices[0].delta, "reasoning_content") and chunk.choices[0].delta.reasoning_content:
                    chunk_content = chunk.choices[0].delta.reasoning_content
                elif chunk.choices[0].delta.content:
                    chunk_content = chunk.choices[0].delta.content

                if chunk_content:
                    # 对内容进行拼音标注处理
                    processed_chunk = PinyinConverter.extract_and_add_pinyin(chunk_content)
                    self.signals.new_chunk.emit(processed_chunk)
                    # 更新进度
                    self.progress = min(self.progress + 2, 95)
                    self.signals.progress_update.emit(self.progress)

                time.sleep(0.05)

            self.signals.progress_update.emit(100)
            self.signals.finished.emit()

        except Exception as e:
            if not self.is_cancelled:
                error_str = f"生成诗句失败: {str(e)}"
                if "invalid_model" in str(e):
                    error_str += "\n提示：模型不存在或无权限"
                elif "401" in str(e):
                    error_str += "\n提示：API Key无效，请检查密钥"
                elif "429" in str(e):
                    error_str += "\n提示：请求过于频繁，请稍后再试"
                self.signals.error.emit(error_str)
                self.signals.debug_info.emit(error_str)
            else:
                self.signals.finished.emit()


# 后台线程类
class ApiWorker(QThread):
    def __init__(self, api, function_type, *args):
        super().__init__()
        self.api = api
        self.function_type = function_type
        self.args = args
        self.is_aborting = False

    def run(self):
        try:
            if self.is_aborting:
                return

            if self.function_type == "couplet":
                upper_sentence, user_requirements = self.args
                self.api.couplet_stream(upper_sentence, user_requirements)
            elif self.function_type == "generate":
                keywords, style, user_requirements = self.args
                self.api.generate_poem_stream(keywords, style, user_requirements)
        except Exception as e:
            if not self.is_aborting:
                error_str = f"线程执行错误: {str(e)}"
                self.api.signals.error.emit(error_str)
                self.api.signals.debug_info.emit(error_str)

    def abort(self):
        self.is_aborting = True
        if self.api:
            self.api.cancel_request()


# 功能任务管理器
class FunctionTaskManager:
    def __init__(self, api_key, base_url, model, debug, rpm_limit):
        # 为每个功能创建独立的API实例
        self.couplet_api = PoetryAPI(api_key, base_url, model, debug, rpm_limit)
        self.generate_api = PoetryAPI(api_key, base_url, model, debug, rpm_limit)

        # 为每个功能创建独立的线程
        self.couplet_worker = None
        self.generate_worker = None

        # 任务状态
        self.couplet_running = False
        self.generate_running = False

    def start_couplet_task(self, upper_sentence, user_requirements):
        # 如果已有任务，先取消
        if self.couplet_worker and self.couplet_worker.isRunning():
            self.couplet_worker.abort()
            self.couplet_worker.wait()

        # 创建新任务
        self.couplet_worker = ApiWorker(self.couplet_api, "couplet", upper_sentence, user_requirements)
        self.couplet_running = True
        self.couplet_worker.start()
        return self.couplet_api.signals

    def start_generate_task(self, keywords, style, user_requirements):
        # 如果已有任务，先取消
        if self.generate_worker and self.generate_worker.isRunning():
            self.generate_worker.abort()
            self.generate_worker.wait()

        # 创建新任务
        self.generate_worker = ApiWorker(self.generate_api, "generate", keywords, style, user_requirements)
        self.generate_running = True
        self.generate_worker.start()
        return self.generate_api.signals

    def cancel_couplet_task(self):
        if self.couplet_worker and self.couplet_worker.isRunning():
            self.couplet_worker.abort()
            self.couplet_worker.wait()
        self.couplet_running = False

    def cancel_generate_task(self):
        if self.generate_worker and self.generate_worker.isRunning():
            self.generate_worker.abort()
            self.generate_worker.wait()
        self.generate_running = False

    def is_couplet_running(self):
        return self.couplet_running and self.couplet_worker and self.couplet_worker.isRunning()

    def is_generate_running(self):
        return self.generate_running and self.generate_worker and self.generate_worker.isRunning()

    def update_debug_mode(self, debug):
        self.couplet_api.debug = debug
        self.generate_api.debug = debug

    def update_rpm_limit(self, rpm_limit):
        self.couplet_api.rpm_limit = rpm_limit
        self.generate_api.rpm_limit = rpm_limit


# 主窗口类
class PoetryApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.task_manager = None  # 使用任务管理器替代单一API实例
        self.config = AppConfig()
        self.current_tab = ""
        self.debug_mode = True
        # 用于记录已绑定的信号，避免重复绑定
        self.bound_signals = {"couplet": None, "generate": None}
        # 用于去重的内容缓存
        self.content_cache = {"couplet": set(), "generate": set()}
        self.init_ui()

    def init_ui(self):
        # 窗口基本属性
        self.setWindowTitle('儿童诗歌对句游戏')
        self.setGeometry(100, 100, 800, 650)
        self.setMinimumSize(750, 550)

        # 设置界面样式
        self.app = QApplication.instance()  # 获取应用实例
        self.set_style()

        # 创建中心部件和主布局
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        main_layout = QVBoxLayout(central_widget)
        main_layout.setContentsMargins(10, 10, 10, 10)
        main_layout.setSpacing(10)

        # 添加标题
        title_label = QLabel('✨ 儿童诗歌对句游戏 ✨')
        title_font = QFont("SimHei", 18, QFont.Bold)
        title_label.setFont(title_font)
        title_label.setAlignment(Qt.AlignCenter)
        title_label.setStyleSheet("margin: 5px 0px; color: #2c3e50;")
        main_layout.addWidget(title_label)

        # ---------------------- 全局API配置区域（位于两个功能上方） ----------------------
        api_group = QGroupBox("API配置")
        api_group.setStyleSheet("QGroupBox {font-weight: bold; color: #34495e;}")
        api_layout = QVBoxLayout()
        api_layout.setContentsMargins(8, 8, 8, 8)
        api_layout.setSpacing(8)

        grid_layout = QGridLayout()
        grid_layout.setContentsMargins(0, 0, 0, 0)
        grid_layout.setSpacing(8)
        grid_layout.setColumnStretch(1, 1)

        # API Key
        grid_layout.addWidget(QLabel("API Key:"), 0, 0, Qt.AlignRight | Qt.AlignVCenter)
        self.api_key_edit = QLineEdit()
        self.api_key_edit.setEchoMode(QLineEdit.PasswordEchoOnEdit)
        grid_layout.addWidget(self.api_key_edit, 0, 1)

        # Base URL
        grid_layout.addWidget(QLabel("Base URL:"), 1, 0, Qt.AlignRight | Qt.AlignVCenter)
        self.base_url_edit = QLineEdit()
        self.base_url_edit.setPlaceholderText("https://qianfan.baidubce.com/v2")
        grid_layout.addWidget(self.base_url_edit, 1, 1)

        # 模型选择
        grid_layout.addWidget(QLabel("模型:"), 2, 0, Qt.AlignRight | Qt.AlignVCenter)
        self.model_combo = QComboBox()
        self.model_combo.addItems([
            "ernie-bot-turbo",
            "ernie-4.5-turbo-128k",
            "ernie-4.5-turbo-vl-32k",
            "deepseek-r1",
            "ernie-speed-128k",
            "llama-4-maverick-17b-128e-instruct"
        ])
        self.model_combo.setEditable(True)
        self.model_combo.setCompleter(self.model_combo.completer())
        self.model_combo.setInsertPolicy(QComboBox.InsertAtTop)
        grid_layout.addWidget(self.model_combo, 2, 1)

        # RPM限制设置
        grid_layout.addWidget(QLabel("RPM限制:"), 3, 0, Qt.AlignRight | Qt.AlignVCenter)
        self.rpm_limit_edit = QLineEdit()
        self.rpm_limit_edit.setText("10")
        self.rpm_limit_edit.setToolTip("每分钟最大请求次数，免费Key建议设为8-10")
        grid_layout.addWidget(self.rpm_limit_edit, 3, 1)

        # 连接按钮和记住配置
        connect_layout = QHBoxLayout()
        self.remember_checkbox = QCheckBox("记住配置")
        self.connect_btn = QPushButton("连接API")
        self.connect_btn.clicked.connect(self.connect_api)
        self.clear_config_btn = QPushButton("清除配置")
        self.clear_config_btn.clicked.connect(self.clear_api_config)
        connect_layout.addWidget(self.remember_checkbox)
        connect_layout.addStretch()
        connect_layout.addWidget(self.connect_btn)
        connect_layout.addWidget(self.clear_config_btn)

        # 调试模式设置
        debug_layout = QHBoxLayout()
        self.debug_checkbox = QCheckBox("开启调试模式")
        self.debug_checkbox.setChecked(self.debug_mode)
        self.debug_checkbox.stateChanged.connect(self.toggle_debug_mode)
        self.toggle_debug_btn = QPushButton("▼")
        self.toggle_debug_btn.setFixedWidth(30)
        self.toggle_debug_btn.clicked.connect(self.toggle_debug_panel)
        debug_layout.addWidget(self.debug_checkbox)
        debug_layout.addStretch()
        debug_layout.addWidget(self.toggle_debug_btn)

        api_layout.addLayout(grid_layout)
        api_layout.addLayout(connect_layout)
        api_layout.addLayout(debug_layout)
        api_group.setLayout(api_layout)
        main_layout.addWidget(api_group)

        # 调试输出区域（全局可见，可折叠）
        self.debug_content = QWidget()
        debug_content_layout = QVBoxLayout(self.debug_content)
        self.debug_output = QTextEdit()
        self.debug_output.setReadOnly(True)
        self.debug_output.setStyleSheet(
            "background-color: #2c3e50; color: #ecf0f1; font-family: monospace; font-size: 9pt;")
        debug_content_layout.addWidget(self.debug_output)
        main_layout.addWidget(self.debug_content)

        # 创建标签页控件（包含两个功能）
        self.tabs = QTabWidget()
        main_layout.addWidget(self.tabs)

        # ---------------------- 对句功能标签页 ----------------------
        couplet_tab = QWidget()
        couplet_layout = QVBoxLayout(couplet_tab)
        couplet_layout.setContentsMargins(0, 0, 0, 0)
        couplet_layout.setSpacing(10)

        # 对句输入区域
        couplet_input_group = QGroupBox("输入诗句上半句")
        couplet_input_layout = QVBoxLayout(couplet_input_group)
        couplet_input_layout.setContentsMargins(6, 6, 6, 6)
        couplet_input_layout.setSpacing(6)

        self.upper_sentence_edit = QTextEdit()
        self.upper_sentence_edit.setPlaceholderText("请输入诗句的上半句，例如：床前明月光")
        self.upper_sentence_edit.setFixedHeight(60)
        self.upper_sentence_edit.textChanged.connect(self.check_couplet_input)

        couplet_req_layout = QHBoxLayout()
        couplet_req_layout.addWidget(QLabel("额外要求："))
        self.couplet_requirements = QLineEdit()
        self.couplet_requirements.setPlaceholderText("例如：解释再简单些")
        couplet_req_layout.addWidget(self.couplet_requirements, 1)

        couplet_btn_layout = QHBoxLayout()
        self.cancel_couplet_btn = QPushButton("取消")
        self.cancel_couplet_btn.setIcon(QIcon.fromTheme("edit-clear", QIcon()))
        self.cancel_couplet_btn.clicked.connect(self.cancel_couplet_task)
        self.cancel_couplet_btn.setEnabled(False)
        self.cancel_couplet_btn.setMinimumHeight(28)
        self.cancel_couplet_btn.setMaximumWidth(80)

        self.couplet_btn = QPushButton("生成对句")
        self.couplet_btn.setIcon(QIcon.fromTheme("document-properties", QIcon()))
        self.couplet_btn.clicked.connect(self.get_couplet)
        self.couplet_btn.setEnabled(False)
        self.couplet_btn.setMinimumHeight(28)

        couplet_btn_layout.addWidget(self.cancel_couplet_btn)
        couplet_btn_layout.addStretch()
        couplet_btn_layout.addWidget(self.couplet_btn)

        # 对句进度条
        self.couplet_progress = QProgressBar()
        self.couplet_progress.setValue(0)

        couplet_input_layout.addWidget(self.upper_sentence_edit)
        couplet_input_layout.addLayout(couplet_req_layout)
        couplet_input_layout.addLayout(couplet_btn_layout)
        couplet_input_layout.addWidget(self.couplet_progress)

        # 对句结果区域
        couplet_result_group = QGroupBox("AI诗歌助手的对句")
        couplet_result_layout = QVBoxLayout(couplet_result_group)
        couplet_result_layout.setContentsMargins(6, 6, 6, 6)
        couplet_result_layout.setSpacing(6)

        couplet_result_toolbar = QHBoxLayout()
        self.copy_couplet_btn = QPushButton("复制")
        self.copy_couplet_btn.setIcon(QIcon.fromTheme("edit-copy", QIcon()))
        self.copy_couplet_btn.clicked.connect(lambda: self.copy_to_clipboard(self.couplet_result))
        self.copy_couplet_btn.setEnabled(False)
        self.copy_couplet_btn.setMaximumWidth(60)

        self.clear_couplet_btn = QPushButton("清空")
        self.clear_couplet_btn.setIcon(QIcon.fromTheme("edit-clear", QIcon()))
        self.clear_couplet_btn.clicked.connect(lambda: self.clear_couplet_content())
        self.clear_couplet_btn.setMaximumWidth(60)

        couplet_result_toolbar.addWidget(self.copy_couplet_btn)
        couplet_result_toolbar.addWidget(self.clear_couplet_btn)
        couplet_result_toolbar.addStretch()

        self.couplet_result = QTextEdit()
        self.couplet_result.setReadOnly(True)
        self.couplet_result.setStyleSheet("background-color: #f8f9fa;")

        couplet_result_layout.addLayout(couplet_result_toolbar)
        couplet_result_layout.addWidget(self.couplet_result)

        couplet_layout.addWidget(couplet_input_group)
        couplet_layout.addWidget(couplet_result_group)
        self.tabs.addTab(couplet_tab, "诗句对句")

        # ---------------------- 生成功能标签页 ----------------------
        generate_tab = QWidget()
        generate_layout = QVBoxLayout(generate_tab)
        generate_layout.setContentsMargins(0, 0, 0, 0)
        generate_layout.setSpacing(10)

        # 创建可滚动区域
        scroll_area = QScrollArea()
        scroll_area.setWidgetResizable(True)
        scroll_content = QWidget()
        scroll_layout = QVBoxLayout(scroll_content)
        scroll_layout.setContentsMargins(0, 0, 0, 0)
        scroll_layout.setSpacing(10)
        scroll_area.setWidget(scroll_content)
        generate_layout.addWidget(scroll_area)

        # 输入区域
        input_group = QGroupBox("输入创作关键词")
        input_layout = QVBoxLayout()
        input_layout.setContentsMargins(6, 6, 6, 6)
        input_layout.setSpacing(6)

        # 关键词输入
        self.keywords_edit = QLineEdit()
        self.keywords_edit.setPlaceholderText("请输入关键词（用逗号分隔），例如：桃花、春天、小朋友")
        self.keywords_edit.textChanged.connect(self.check_keywords_input)
        self.keywords_edit.setStyleSheet("""
            QLineEdit::placeholder {
                color: #7f8c8d;
                font-style: italic;
            }
        """)

        # 诗歌风格选择
        style_layout = QHBoxLayout()
        style_layout.setContentsMargins(0, 0, 0, 0)
        style_layout.addWidget(QLabel("诗歌风格："))
        self.style_combo = QComboBox()
        self.style_combo.addItems(["唐诗", "宋词", "五言绝句", "七言绝句"])
        self.style_combo.setMinimumWidth(120)
        style_layout.addWidget(self.style_combo)
        style_layout.addStretch()

        # 用户额外要求
        req_layout = QHBoxLayout()
        req_layout.setContentsMargins(0, 0, 0, 0)
        req_layout.addWidget(QLabel("额外要求："))
        self.generate_requirements = QLineEdit()
        self.generate_requirements.setPlaceholderText("例如：多写春天的景色、语言更活泼")
        req_layout.addWidget(self.generate_requirements, 1)

        # 示例提示
        example_label = QLabel("💡 推荐示例：'月亮、星星、夜晚'、'荷花、夏天、池塘'")
        example_label.setStyleSheet("color: #7f8c8d; font-size: 9pt;")
        example_label.setWordWrap(True)

        # 按钮区域
        btn_layout = QHBoxLayout()
        self.generate_btn = QPushButton("生成诗歌")
        self.generate_btn.setIcon(QIcon.fromTheme("document-properties", QIcon()))
        self.generate_btn.clicked.connect(self.generate_poem)
        self.generate_btn.setEnabled(False)
        self.generate_btn.setMinimumHeight(28)

        self.cancel_generate_btn = QPushButton("取消")
        self.cancel_generate_btn.setIcon(QIcon.fromTheme("edit-clear", QIcon()))
        self.cancel_generate_btn.clicked.connect(self.cancel_generate_task)
        self.cancel_generate_btn.setEnabled(False)
        self.cancel_generate_btn.setMinimumHeight(28)
        self.cancel_generate_btn.setMaximumWidth(80)

        btn_layout.addWidget(self.cancel_generate_btn)
        btn_layout.addStretch()
        btn_layout.addWidget(self.generate_btn)

        # 生成进度条
        self.generate_progress = QProgressBar()
        self.generate_progress.setValue(0)

        input_layout.addWidget(self.keywords_edit)
        input_layout.addLayout(style_layout)
        input_layout.addLayout(req_layout)
        input_layout.addWidget(example_label)
        input_layout.addLayout(btn_layout)
        input_layout.addWidget(self.generate_progress)
        input_group.setLayout(input_layout)
        scroll_layout.addWidget(input_group)

        # 结果区域
        result_group = QGroupBox("AI诗歌助手的创作（含古诗推荐）")
        result_layout = QVBoxLayout()
        result_layout.setContentsMargins(6, 6, 6, 6)
        result_layout.setSpacing(6)

        # 结果工具栏
        result_toolbar = QHBoxLayout()
        self.copy_poem_btn = QPushButton("复制")
        self.copy_poem_btn.setIcon(QIcon.fromTheme("edit-copy", QIcon()))
        self.copy_poem_btn.clicked.connect(lambda: self.copy_to_clipboard(self.poem_result))
        self.copy_poem_btn.setEnabled(False)
        self.copy_poem_btn.setMaximumWidth(60)

        self.clear_poem_btn = QPushButton("清空")
        self.clear_poem_btn.setIcon(QIcon.fromTheme("edit-clear", QIcon()))
        self.clear_poem_btn.clicked.connect(lambda: self.clear_poem_content())
        self.clear_poem_btn.setMaximumWidth(60)

        result_toolbar.addWidget(self.copy_poem_btn)
        result_toolbar.addWidget(self.clear_poem_btn)
        result_toolbar.addStretch()

        # 结果显示
        self.poem_result = QTextEdit()
        self.poem_result.setReadOnly(True)
        self.poem_result.setStyleSheet("background-color: #f8f9fa;")
        self.poem_result.setLineWrapMode(QTextEdit.WidgetWidth)
        self.poem_result.setWordWrapMode(QTextOption.WordWrap)

        result_layout.addLayout(result_toolbar)
        result_layout.addWidget(self.poem_result)
        result_group.setLayout(result_layout)
        scroll_layout.addWidget(result_group)

        self.tabs.addTab(generate_tab, "关键词创作")

        # 状态栏
        self.statusBar().showMessage("未连接到API")

        # 加载保存的配置
        self.load_saved_config()

        # 标签页切换信号
        self.tabs.currentChanged.connect(self.on_tab_changed)
        self.on_tab_changed(0)  # 初始化第一个标签页

    def load_saved_config(self):
        """加载保存的API配置"""
        api_key, base_url, model = self.config.load_config()
        if api_key:
            self.api_key_edit.setText(api_key)
            self.base_url_edit.setText(base_url)
            # 设置模型
            index = self.model_combo.findText(model)
            if index != -1:
                self.model_combo.setCurrentIndex(index)
            else:
                self.model_combo.setCurrentText(model)
            self.remember_checkbox.setChecked(True)
            self.debug_output.append(f"[{time.strftime('%H:%M:%S')}] 已加载保存的配置")

    def set_style(self):
        """设置应用程序样式"""
        style = """
            QWidget {
                font-family: "Microsoft YaHei", SimHei, sans-serif;
                font-size: 10pt;
            }
            QPushButton {
                background-color: #3498db;
                color: white;
                border: none;
                padding: 5px 10px;
                border-radius: 3px;
            }
            QPushButton:hover {
                background-color: #2980b9;
            }
            QPushButton:disabled {
                background-color: #bdc3c7;
                color: #ecf0f1;
            }
            QGroupBox {
                border: 1px solid #bdc3c7;
                border-radius: 4px;
                margin-top: 10px;
            }
            QGroupBox::title {
                subcontrol-origin: margin;
                left: 10px;
                padding: 0 3px 0 3px;
            }
            QLineEdit, QTextEdit, QComboBox {
                padding: 4px;
                border: 1px solid #bdc3c7;
                border-radius: 3px;
            }
            QProgressBar {
                height: 8px;
                border-radius: 4px;
                background-color: #ecf0f1;
            }
            QProgressBar::chunk {
                background-color: #2ecc71;
                border-radius: 4px;
            }
        """
        if self.app:
            self.app.setStyleSheet(style)

    def toggle_debug_panel(self):
        """切换调试面板显示/隐藏"""
        is_visible = self.debug_content.isVisible()
        self.debug_content.setVisible(not is_visible)
        self.toggle_debug_btn.setText("▲" if not is_visible else "▼")

    def toggle_debug_mode(self, state):
        """切换调试模式"""
        self.debug_mode = (state == Qt.Checked)
        self.debug_content.setVisible(self.debug_mode)
        if self.task_manager:
            self.task_manager.update_debug_mode(self.debug_mode)
            debug_msg = f"[{time.strftime('%H:%M:%S')}] 调试模式已{'开启' if self.debug_mode else '关闭'}"
            self.debug_output.append(debug_msg)

    def on_tab_changed(self, index):
        """切换标签页时更新当前标签标识"""
        if index == 0:
            self.current_tab = "couplet"
        else:
            self.current_tab = "generate"

        # 更新按钮状态以反映当前任务状态
        self.update_button_states()

    def update_button_states(self):
        """根据每个功能的任务状态更新按钮"""
        if not self.task_manager:
            return

        # 更新对句功能按钮状态
        couplet_running = self.task_manager.is_couplet_running()
        self.couplet_btn.setEnabled(not couplet_running and self.upper_sentence_edit.toPlainText().strip())
        self.cancel_couplet_btn.setEnabled(couplet_running)
        self.copy_couplet_btn.setEnabled(self.couplet_result.toPlainText().strip())

        # 更新生成功能按钮状态
        generate_running = self.task_manager.is_generate_running()
        self.generate_btn.setEnabled(not generate_running and self.keywords_edit.text().strip())
        self.cancel_generate_btn.setEnabled(generate_running)
        self.copy_poem_btn.setEnabled(self.poem_result.toPlainText().strip())

    def check_couplet_input(self):
        """检查对句输入"""
        if self.task_manager and not self.task_manager.is_couplet_running() and self.upper_sentence_edit.toPlainText().strip():
            self.couplet_btn.setEnabled(True)
        else:
            self.couplet_btn.setEnabled(False)

    def check_keywords_input(self):
        """检查关键词输入"""
        if self.task_manager and not self.task_manager.is_generate_running() and self.keywords_edit.text().strip():
            self.generate_btn.setEnabled(True)
        else:
            self.generate_btn.setEnabled(False)

    def connect_api(self):
        """连接API - 创建任务管理器，为每个功能提供独立实例"""
        api_key = self.api_key_edit.text().strip()
        base_url = self.base_url_edit.text().strip()
        model = self.model_combo.currentText().strip()

        # 获取RPM限制设置
        try:
            rpm_limit = int(self.rpm_limit_edit.text().strip())
            if rpm_limit < 1 or rpm_limit > 100:
                raise ValueError
        except ValueError:
            QMessageBox.warning(self, "输入错误", "RPM限制必须是1-100之间的整数")
            return

        # 基础输入校验
        if not api_key:
            QMessageBox.warning(self, "输入错误",
                                f"请输入API Key\n获取地址：https://console.bce.baidu.com/iam/#/iam/apikey/list")
            return
        if not base_url:
            QMessageBox.warning(self, "输入错误", f"请输入Base URL\n百度千帆默认：https://qianfan.baidubce.com/v2")
            return
        if not model:
            QMessageBox.warning(self, "输入错误", "请选择或输入模型名称")
            return

        # 显示连接中状态
        self.debug_output.append(f"[{time.strftime('%H:%M:%S')}] 尝试连接API：{base_url}，模型：{model}")
        self.statusBar().showMessage("正在连接API...")
        self.connect_btn.setEnabled(False)

        # 保存配置
        if self.remember_checkbox.isChecked():
            self.config.save_config(api_key, base_url, model)
            self.debug_output.append(f"[{time.strftime('%H:%M:%S')}] 已保存API配置（含模型：{model}）")
        else:
            self.config.clear_config()

        # 启动独立线程验证API连接
        class ConnectThread(QThread):
            result_signal = pyqtSignal(bool, str, int)
            debug_signal = pyqtSignal(str)

            def __init__(self, api_key, base_url, model, rpm_limit):
                super().__init__()
                self.api_key = api_key
                self.base_url = base_url
                self.model = model
                self.rpm_limit = rpm_limit

            def run(self):
                try:
                    self.debug_signal.emit(f"[{time.strftime('%H:%M:%S')}] 创建OpenAI客户端")
                    client = OpenAI(
                        api_key=self.api_key,
                        base_url=self.base_url
                    )

                    self.debug_signal.emit(f"[{time.strftime('%H:%M:%S')}] 发送测试请求（模型：{self.model}）")
                    response = client.chat.completions.create(
                        model=self.model,
                        messages=[{"role": "user", "content": "测试连接，返回'连接成功'即可"}],
                        stream=False,
                        max_tokens=10
                    )

                    if response.choices and response.choices[0].message.content:
                        test_result = response.choices[0].message.content.strip()
                        self.debug_signal.emit(f"[{time.strftime('%H:%M:%S')}] 测试响应：{test_result}")
                        self.result_signal.emit(True, f"API连接成功（模型：{self.model}）", self.rpm_limit)
                    else:
                        self.result_signal.emit(False, "测试响应为空，连接失败", self.rpm_limit)

                except Exception as e:
                    error_str = f"连接失败：{str(e)}"
                    if "invalid_model" in str(e):
                        error_str += "\n提示：模型不存在或无权限"
                    elif "401" in str(e):
                        error_str += "\n提示：API Key无效或权限不足"
                    elif "403" in str(e):
                        error_str += "\n提示：无该模型访问权限"
                    elif "429" in str(e):
                        error_str += "\n提示：当前API请求过于频繁"
                    self.debug_signal.emit(f"[{time.strftime('%H:%M:%S')}] {error_str}")
                    self.result_signal.emit(False, error_str, self.rpm_limit)

        # 启动连接线程并绑定回调
        self.connect_thread = ConnectThread(api_key, base_url, model, rpm_limit)
        self.connect_thread.result_signal.connect(self.on_connect_result)
        self.connect_thread.debug_signal.connect(self.debug_output.append)
        self.connect_thread.start()

    def on_connect_result(self, success, message, rpm_limit):
        """处理API连接结果 - 初始化任务管理器"""
        self.statusBar().showMessage(message)
        self.connect_btn.setEnabled(True)

        if success:
            # 连接成功，初始化任务管理器（为两个功能创建独立API实例）
            self.task_manager = FunctionTaskManager(
                api_key=self.api_key_edit.text().strip(),
                base_url=self.base_url_edit.text().strip(),
                model=self.model_combo.currentText().strip(),
                debug=self.debug_mode,
                rpm_limit=rpm_limit
            )

            # 更新按钮状态
            self.update_button_states()
            QMessageBox.information(self, "连接成功",
                                    f"已成功连接到API！\n当前模型：{self.model_combo.currentText()}\nRPM限制：{rpm_limit}次/分钟")
        else:
            # 连接失败，提示错误信息
            QMessageBox.warning(self, "连接失败", message)

    def get_couplet(self):
        """触发对句生成功能 - 使用独立的API实例和线程"""
        upper_sentence = self.upper_sentence_edit.toPlainText().strip()
        user_requirements = self.couplet_requirements.text().strip()

        # 输入校验
        if not upper_sentence:
            QMessageBox.warning(self, "输入错误", "请输入诗句上半句")
            return
        if not self.task_manager:
            QMessageBox.warning(self, "未连接API", "请先在上方API配置区域连接API")
            return

        # 清空之前的结果和信号绑定
        self.clear_couplet_content()
        self.couplet_progress.setValue(0)

        # 关键修复：取消之前的信号绑定
        if self.bound_signals["couplet"]:
            signals = self.bound_signals["couplet"]
            try:
                signals.new_chunk.disconnect(self.on_couplet_chunk)
                signals.finished.disconnect(self.on_couplet_finished)
                signals.error.disconnect(self.on_couplet_error)
                signals.status_update.disconnect(self.update_status_for_couplet)
                signals.progress_update.disconnect(self.couplet_progress.setValue)
            except Exception as e:
                self.debug_output.append(f"[{time.strftime('%H:%M:%S')}] 信号解绑错误: {str(e)}")

        # 启动对句任务，获取信号对象
        signals = self.task_manager.start_couplet_task(upper_sentence, user_requirements)

        # 重新绑定信号（确保唯一绑定）
        signals.new_chunk.connect(self.on_couplet_chunk)
        signals.finished.connect(self.on_couplet_finished)
        signals.error.connect(self.on_couplet_error)
        signals.status_update.connect(self.update_status_for_couplet)
        signals.progress_update.connect(self.couplet_progress.setValue)

        self.bound_signals["couplet"] = signals

        # 更新按钮状态
        self.update_button_states()

    def generate_poem(self):
        """触发关键词生成诗歌功能 - 使用独立的API实例和线程"""
        keywords = self.keywords_edit.text().strip()
        style = self.style_combo.currentText()
        user_requirements = self.generate_requirements.text().strip()

        # 输入校验
        if not keywords:
            QMessageBox.warning(self, "输入错误", "请输入创作关键词（用逗号分隔）")
            return
        if not self.task_manager:
            QMessageBox.warning(self, "未连接API", "请先在上方API配置区域连接API")
            return

        # 清空之前的结果和信号绑定
        self.clear_poem_content()
        self.generate_progress.setValue(0)

        # 关键修复：取消之前的信号绑定
        if self.bound_signals["generate"]:
            signals = self.bound_signals["generate"]
            try:
                signals.new_chunk.disconnect(self.on_generate_chunk)
                signals.finished.disconnect(self.on_generate_finished)
                signals.error.disconnect(self.on_generate_error)
                signals.status_update.disconnect(self.update_status_for_generate)
                signals.progress_update.disconnect(self.generate_progress.setValue)
            except Exception as e:
                self.debug_output.append(f"[{time.strftime('%H:%M:%S')}] 信号解绑错误: {str(e)}")

        # 启动生成任务，获取信号对象
        signals = self.task_manager.start_generate_task(keywords, style, user_requirements)

        # 重新绑定信号（确保唯一绑定）
        signals.new_chunk.connect(self.on_generate_chunk)
        signals.finished.connect(self.on_generate_finished)
        signals.error.connect(self.on_generate_error)
        signals.status_update.connect(self.update_status_for_generate)
        signals.progress_update.connect(self.generate_progress.setValue)

        self.bound_signals["generate"] = signals

        # 更新按钮状态
        self.update_button_states()

    def cancel_couplet_task(self):
        """取消对句任务"""
        if self.task_manager and self.task_manager.is_couplet_running():
            self.statusBar().showMessage("正在取消对句任务...")
            self.task_manager.cancel_couplet_task()
            self.couplet_progress.setValue(0)
            self.update_button_states()
            self.statusBar().showMessage("对句任务已取消")
        else:
            QMessageBox.information(self, "提示", "没有正在进行的对句任务")

    def cancel_generate_task(self):
        """取消生成任务"""
        if self.task_manager and self.task_manager.is_generate_running():
            self.statusBar().showMessage("正在取消生成任务...")
            self.task_manager.cancel_generate_task()
            self.generate_progress.setValue(0)
            self.update_button_states()
            self.statusBar().showMessage("生成任务已取消")
        else:
            QMessageBox.information(self, "提示", "没有正在进行的生成任务")

    # 对句功能的信号处理函数
    def on_couplet_chunk(self, chunk):
        """优化内容显示，避免重复段落"""
        # 去除前后空格和换行
        clean_chunk = chunk.strip()
        if not clean_chunk:
            return

        # 检查内容是否已存在于缓存中（去重逻辑）
        if clean_chunk in self.content_cache["couplet"]:
            return  # 跳过重复内容

        # 检查最后一行是否与当前内容重复
        cursor = self.couplet_result.textCursor()
        cursor.movePosition(cursor.End)
        cursor.movePosition(cursor.StartOfLine, cursor.KeepAnchor)
        last_line = cursor.selectedText().strip()

        if last_line == clean_chunk:
            return  # 跳过重复内容

        # 添加到缓存并显示
        self.content_cache["couplet"].add(clean_chunk)
        self.couplet_result.insertPlainText(chunk)
        self.couplet_result.moveCursor(self.couplet_result.textCursor().End)

    def on_couplet_finished(self):
        self.copy_couplet_btn.setEnabled(True)
        self.update_button_states()
        self.statusBar().showMessage("对句生成完成！")

    def on_couplet_error(self, error_msg):
        self.couplet_result.insertPlainText(f"\n❌ 错误：{error_msg}")
        self.couplet_result.moveCursor(self.couplet_result.textCursor().End)
        self.update_button_states()
        self.statusBar().showMessage("对句操作失败")

    def update_status_for_couplet(self, status):
        # 如果当前在对句标签页或没有任务在运行，更新状态栏
        if self.current_tab == "couplet" or (not self.task_manager.is_generate_running()):
            self.statusBar().showMessage(status)

    # 生成功能的信号处理函数
    def on_generate_chunk(self, chunk):
        """优化内容显示，避免重复段落"""
        # 去除前后空格和换行
        clean_chunk = chunk.strip()
        if not clean_chunk:
            return

        # 检查内容是否已存在于缓存中（去重逻辑）
        if clean_chunk in self.content_cache["generate"]:
            return  # 跳过重复内容

        # 检查最后一行是否与当前内容重复
        cursor = self.poem_result.textCursor()
        cursor.movePosition(cursor.End)
        cursor.movePosition(cursor.StartOfLine, cursor.KeepAnchor)
        last_line = cursor.selectedText().strip()

        if last_line == clean_chunk:
            return  # 跳过重复内容

        # 添加到缓存并显示
        self.content_cache["generate"].add(clean_chunk)
        self.poem_result.insertPlainText(chunk)
        self.poem_result.moveCursor(self.poem_result.textCursor().End)

    def on_generate_finished(self):
        self.copy_poem_btn.setEnabled(True)
        self.update_button_states()
        self.statusBar().showMessage(f"{self.style_combo.currentText()}生成完成！")

    def on_generate_error(self, error_msg):
        self.poem_result.insertPlainText(f"\n❌ 错误：{error_msg}")
        self.poem_result.moveCursor(self.poem_result.textCursor().End)
        self.update_button_states()
        self.statusBar().showMessage("生成操作失败")

    def update_status_for_generate(self, status):
        # 如果当前在生成标签页或没有任务在运行，更新状态栏
        if self.current_tab == "generate" or (not self.task_manager.is_couplet_running()):
            self.statusBar().showMessage(status)

    def copy_to_clipboard(self, text_edit):
        """复制文本到剪贴板"""
        text = text_edit.toPlainText()
        if text.strip():
            clipboard = QApplication.clipboard()
            clipboard.setText(text)
            self.statusBar().showMessage("内容已复制到剪贴板（3秒后消失）")
            # 3秒后恢复状态栏默认信息
            QTimer.singleShot(3000, self.restore_status_bar)

    def restore_status_bar(self):
        """恢复状态栏默认信息"""
        if "复制到剪贴板" in self.statusBar().currentMessage():
            if self.task_manager:
                # 检查是否有运行中的任务并显示相应状态
                if self.task_manager.is_couplet_running():
                    self.statusBar().showMessage("对句任务正在进行中...")
                elif self.task_manager.is_generate_running():
                    self.statusBar().showMessage("生成任务正在进行中...")
                else:
                    self.statusBar().showMessage("API已连接，可继续操作")
            else:
                self.statusBar().showMessage("未连接到API")

    def clear_api_config(self):
        """清除API配置 - 同时取消所有任务"""
        # 取消所有任务
        if self.task_manager:
            self.task_manager.cancel_couplet_task()
            self.task_manager.cancel_generate_task()
            self.task_manager = None

        self.api_key_edit.clear()
        self.base_url_edit.clear()
        self.model_combo.setCurrentIndex(0)
        self.rpm_limit_edit.setText("10")
        self.remember_checkbox.setChecked(False)
        self.config.clear_config()

        # 重置进度条
        self.couplet_progress.setValue(0)
        self.generate_progress.setValue(0)

        # 更新状态
        self.debug_output.append(f"[{time.strftime('%H:%M:%S')}] 已清除API配置")
        self.statusBar().showMessage("API配置已清除")
        self.update_button_states()

    def clear_couplet_content(self):
        """清空对句内容并重置缓存"""
        self.couplet_result.clear()
        self.copy_couplet_btn.setEnabled(False)
        self.content_cache["couplet"].clear()

    def clear_poem_content(self):
        """清空诗歌内容并重置缓存"""
        self.poem_result.clear()
        self.copy_poem_btn.setEnabled(False)
        self.content_cache["generate"].clear()

    def closeEvent(self, event):
        """窗口关闭事件处理 - 优雅关闭所有任务"""
        if self.task_manager:
            self.task_manager.cancel_couplet_task()
            self.task_manager.cancel_generate_task()

        if hasattr(self, "connect_thread") and self.connect_thread.isRunning():
            self.connect_thread.quit()
            self.connect_thread.wait()

        event.accept()


# 程序入口
if __name__ == '__main__':
    try:
        # 安装依赖提示 - 首次运行时需要
        try:
            import pypinyin
        except ImportError:
            print("正在安装依赖库 pypinyin...")
            import subprocess

            subprocess.check_call([sys.executable, "-m", "pip", "install", "pypinyin"])
            import pypinyin

        # 初始化Qt应用
        app = QApplication(sys.argv)
        app.setStyle("Fusion")
        app.setApplicationName("儿童诗歌对句游戏")
        app.setApplicationVersion("1.3")

        # 创建并显示主窗口
        window = PoetryApp()
        window.show()

        # 运行应用
        sys.exit(app.exec_())

    except Exception as e:
        print(f"程序启动失败: {str(e)}")
        import traceback

        traceback.print_exc()
        input("按回车键退出...")
        sys.exit(1)
